#include "analyzer.h"
#include <fstream>
#include <sstream>

std::vector<Stock> StockAnalyzer::loadFromCSV(const std::string& filename) {
    std::vector<Stock> stocks;
    std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + filename);
    }

    std::string line;
    // 验证标题行
    std::getline(file, line);
    if (line != "code,name,price,high,low,change_percent,volume,date") {
        throw std::runtime_error("CSV文件格式错误: 标题行不匹配");
    }
    
    while (std::getline(file, line)) {
        std::stringstream ss(line);
        Stock stock;
        std::string field;
        std::vector<std::string> fields;
        
        // 分割并验证字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }
        
        if (fields.size() != 8) {
            throw std::runtime_error("CSV格式错误: 每行应有8个字段");
        }
        
        // 解析并验证各字段
        stock.code = fields[0];
        if (stock.code.empty()) {
            throw std::runtime_error("股票代码不能为空");
        }
        
        // 根据代码识别市场
        if (stock.code.find(".HK") != std::string::npos) {
            stock.market = HK;
            stock.currency = "HKD";
        } else if (stock.code.find(".") == std::string::npos) {
            stock.market = US;
            stock.currency = "USD";
        } else {
            stock.market = CN;
            stock.currency = "CNY";
        }
        
        stock.name = fields[1];
        
        try {
            stock.price = std::stod(fields[2]);
            stock.high = std::stod(fields[3]);
            stock.low = std::stod(fields[4]);
            stock.change_percent = std::stod(fields[5]);
            stock.volume = std::stod(fields[6]);
            
            // 价格合理性验证
            if (stock.price <= 0) {
                throw std::runtime_error("价格必须大于0: " + std::to_string(stock.price));
            }
            if (stock.high < stock.low) {
                throw std::runtime_error("最高价不能低于最低价");
            }
            if (stock.price > stock.high || stock.price < stock.low) {
                throw std::runtime_error("当前价格必须在最高价和最低价之间");
            }
            
            // 成交量验证
            if (stock.volume < 0) {
                throw std::runtime_error("成交量不能为负数: " + std::to_string(stock.volume));
            }
            // 设置合理的成交量上限(10亿股)
            if (stock.volume > 1e9) {
                throw std::runtime_error("成交量超过合理上限(10亿股): " + std::to_string(stock.volume));
            }
        } catch (const std::exception& e) {
            throw std::runtime_error("数值转换错误: " + std::string(e.what()));
        }
        
        // 验证日期格式 (YYYY-MM-DD)
        stock.date = fields[7];
        static const std::regex date_regex("^\\d{4}-\\d{2}-\\d{2}$");
        if (!std::regex_match(stock.date, date_regex)) {
            throw std::runtime_error("日期格式错误, 应为YYYY-MM-DD");
        }
        
        stocks.push_back(stock);
    }
    
    return stocks;
}

#include <fstream>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <stdexcept>
#include <chrono>
#include <iomanip>
#include <limits>

// 日志宏定义
#define LOG_INFO(msg) std::cout << "[INFO] " << __FUNCTION__ << ": " << msg << std::endl
#define LOG_WARNING(msg) std::cerr << "[WARNING] " << __FUNCTION__ << ": " << msg << std::endl
#define LOG_ERROR(msg) std::cerr << "[ERROR] " << __FUNCTION__ << ": " << msg << std::endl

// 计时宏定义
#define TIME_START() auto start = std::chrono::high_resolution_clock::now()
#define TIME_END(func) \
    auto end = std::chrono::high_resolution_clock::now(); \
    std::chrono::duration<double> elapsed = end - start; \
    LOG_INFO(func << " took " << elapsed.count() << " seconds")

using namespace std;
using namespace TechnicalAnalysis;

vector<double> TechnicalAnalysis::calculateStrategyScore(
    const vector<Stock>& stocks,
    StrategyType type,
    const StrategyWeights& weights) {
    TIME_START();
    vector<double> scores;
    if (stocks.empty()) {
        LOG_WARNING("空股票数据输入");
        return scores;
    }

    try {
        scores.resize(stocks.size());
        vector<double> prices;
        prices.reserve(stocks.size());
        for (const auto& stock : stocks) {
            prices.push_back(stock.price);
        }

        // 计算各技术指标
        auto ma = calculateMA(prices, 20);
        auto rsi = calculateRSI(prices);
        auto bands = calculateBollingerBands(prices);
        auto atr = calculateATR(highs, lows, prices);
        
        vector<double> dif, dea, macd;
        calculateMACD(prices, dif, dea, macd);

        // 准备KDJ计算所需数据
        vector<double> highs(stocks.size()), lows(stocks.size());
        for (size_t i = 0; i < stocks.size(); ++i) {
            highs[i] = stocks[i].high;
            lows[i] = stocks[i].low;
        }
        auto kdj = calculateKDJ(highs, lows, prices);

        // 计算综合评分
        for (size_t i = 0; i < stocks.size(); ++i) {
            double score = 0.0;
            size_t idx = i - (stocks.size() - ma.size()); // 对齐指标索引

            // MA指标评分
            if (idx < ma.size() && i >= 20) {
                double ma_score = (prices[i] > ma[idx]) ? 1.0 : -1.0;
                score += weights.technical * ma_score * 0.25;
            }

            // RSI指标评分
            if (idx < rsi.size() && i >= 14) {
                double rsi_score = 0.0;
                if (rsi[idx] < 30) rsi_score = 1.0; // 超卖
                else if (rsi[idx] > 70) rsi_score = -1.0; // 超买
                score += weights.technical * rsi_score * 0.25;
            }

            // 布林带指标评分
            if (idx < bands.lower.size() && i >= 20) {
                double band_score = 0.0;
                if (prices[i] < bands.lower[idx]) band_score = 1.0; // 接近下轨
                else if (prices[i] > bands.upper[idx]) band_score = -1.0; // 接近上轨
                score += weights.technical * band_score * 0.15;
            }

            // MACD指标评分
            if (i < macd.size()) {
                double macd_score = (macd[i] > 0) ? 1.0 : -1.0;
                score += weights.technical * macd_score * 0.15;
            }

            // KDJ指标评分
            if (i < kdj.k.size()) {
                double kdj_score = 0.0;
                if (kdj.k[i] < 20 && kdj.d[i] < 20) kdj_score = 1.0; // 超卖
                else if (kdj.k[i] > 80 && kdj.d[i] > 80) kdj_score = -1.0; // 超买
                score += weights.technical * kdj_score * 0.15;
            }

            // ATR指标评分 (波动率因子)
            if (idx < atr.size() && i >= period) {
                // 标准化ATR为0-1范围(相对于价格)
                double normalized_atr = atr[idx] / prices[i];
                // 波动率越高对趋势策略越有利
                double atr_score = min(normalized_atr * 10, 1.0); // 假设10%ATR为最大值
                score += weights.technical * atr_score * 0.1;
            }

            // 动量指标评分
            if (i > 0) {
                double momentum = prices[i] - prices[i-1];
                score += weights.momentum * (momentum > 0 ? 1.0 : -1.0);
            }

            scores[i] = score;
        }
    } catch (const exception& e) {
        LOG_ERROR("计算策略评分时出错: " << e.what());
        throw;
    }

    TIME_END("calculateStrategyScore");
    return scores;
}

KDJ TechnicalAnalysis::calculateKDJ(const vector<double>& highs,
                                  const vector<double>& lows,
                                  const vector<double>& closes,
                                  int period) {
    TIME_START();
    KDJ result;
    if (highs.empty() || lows.empty() || closes.empty()) {
        LOG_WARNING("空输入数据");
        return result;
    }
    if (highs.size() != lows.size() || highs.size() != closes.size()) {
        LOG_ERROR("输入数据长度不一致");
        throw invalid_argument("输入数据长度不一致");
    }

    try {
        size_t n = highs.size();
        result.k.resize(n);
        result.d.resize(n);
        result.j.resize(n);

        vector<double> rsv(n, 50.0); // 初始RSV设为50

        for (size_t i = period-1; i < n; ++i) {
            // 计算周期内最高价和最低价
            double highest = *max_element(highs.begin() + i - period + 1, highs.begin() + i + 1);
            double lowest = *min_element(lows.begin() + i - period + 1, lows.begin() + i + 1);

            if (highest != lowest) {
                rsv[i] = (closes[i] - lowest) / (highest - lowest) * 100;
            }

            // 计算K值(快速随机值)
            if (i == period-1) {
                result.k[i] = rsv[i];
            } else {
                result.k[i] = (2.0/3) * result.k[i-1] + (1.0/3) * rsv[i];
            }

            // 计算D值(慢速随机值)
            if (i == period-1) {
                result.d[i] = result.k[i];
            } else {
                result.d[i] = (2.0/3) * result.d[i-1] + (1.0/3) * result.k[i];
            }

            // 计算J值
            result.j[i] = 3 * result.k[i] - 2 * result.d[i];
        }

        // 填充前period-1个数据点
        for (int i = 0; i < period-1; ++i) {
            result.k[i] = 50.0;
            result.d[i] = 50.0;
            result.j[i] = 50.0;
        }
    } catch (const exception& e) {
        LOG_ERROR("计算KDJ指标时出错: " << e.what());
        throw;
    }

    TIME_END("calculateKDJ");
    return result;
}

vector<double> TechnicalAnalysis::calculateATR(const vector<double>& highs,
                                            const vector<double>& lows,
                                            const vector<double>& closes,
                                            int period) {
    TIME_START();
    if (highs.empty() || lows.empty() || closes.empty()) {
        LOG_WARNING("空输入数据");
        return {};
    }
    if (highs.size() != lows.size() || highs.size() != closes.size()) {
        LOG_ERROR("输入数据长度不一致");
        throw invalid_argument("输入数据长度不一致");
    }

    vector<double> atr;
    try {
        size_t n = highs.size();
        vector<double> tr(n, 0.0);
        
        // 计算真实波幅(TR)
        for (size_t i = 0; i < n; ++i) {
            if (i == 0) {
                tr[i] = highs[i] - lows[i];
            } else {
                double tr1 = highs[i] - lows[i];
                double tr2 = abs(highs[i] - closes[i-1]);
                double tr3 = abs(lows[i] - closes[i-1]);
                tr[i] = max({tr1, tr2, tr3});
            }
        }

        // 计算ATR
        atr.resize(n);
        if (n >= period) {
            // 第一个ATR是前period个TR的平均值
            double sum = accumulate(tr.begin(), tr.begin() + period, 0.0);
            atr[period-1] = sum / period;
            
            // 后续ATR使用平滑公式: (前一日ATR*(period-1) + 当日TR)/period
            for (size_t i = period; i < n; ++i) {
                atr[i] = (atr[i-1] * (period-1) + tr[i]) / period;
            }
        }
        
        // 填充不足period的数据点
        for (int i = 0; i < period-1 && i < static_cast<int>(n); ++i) {
            atr[i] = numeric_limits<double>::quiet_NaN();
        }
    } catch (const exception& e) {
        LOG_ERROR("计算ATR指标时出错: " << e.what());
        throw;
    }

    TIME_END("calculateATR");
    return atr;
}

// 保留其他已有函数实现...